﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Data;
using System.Data.Linq;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Net.Mail;
using System.ComponentModel;
using PRT;
using ONCALL_ENTRY;
using Asterisk.NET.Manager;
using Asterisk.NET.Manager.Action;
using Asterisk.NET.Manager.Response;
using Asterisk.NET.FastAGI;
using Asterisk.NET.Manager.Event;
using System.Threading;
using System.Web.Security;

public partial class call : System.Web.UI.Page
{
    const string ASTERISK_HOST = "s131559x.trixbox.fonality.com";
    const int ASTERISK_PORT = 5038;
    const string ASTERISK_LOGINNAME = "remote_mgr";
    const string ASTERISK_LOGINPWD = "0chanc3yo";
    const int TIMEOUT = 10000;

    #region OnCall Variables
    string OnCallConnection = "Data Source=MICHAEL-PC\\SQLEXPRESS;Initial Catalog=ON-CALL;Integrated Security=True";
    List<OnCallEntry> ENTRIES;
    Style labelStyle;
    Style noteStyle;
    Style currentLabelStyle;
    Style currentNoteStyle;
    #endregion

    ManagerConnection manager = new ManagerConnection(ASTERISK_HOST, ASTERISK_PORT, ASTERISK_LOGINNAME, ASTERISK_LOGINPWD);
    AnsweringServiceDataContext db = new AnsweringServiceDataContext();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            int CallID;
            if (Common.HasValue(Request.QueryString["ID"]))
            {
                CallID = Convert.ToInt32(Request.QueryString["ID"]);
                ViewState["CallID"] = CallID;
                SetPageData(CallID);
                DataBind();
            }
            else
                Response.Redirect(ResolveUrl("~/error.aspx"));
        }
        #region OnCall
        ENTRIES = new List<OnCallEntry>();

        //Create styles
        labelStyle = new Style();
        labelStyle.Font.Size = FontUnit.Small;
        labelStyle.Font.Name = "Tahoma";

        currentLabelStyle = new Style();
        currentLabelStyle.Font.Size = FontUnit.Small;
        currentLabelStyle.Font.Name = "Tahoma";
        currentLabelStyle.BackColor = System.Drawing.Color.Yellow;

        // Run only once a postback has occured
        CreateDynamicTable();
        #endregion
    }

    protected void SetPageData(int CallID)
    {
        if (CallID > 0)
        {
            Call call = db.Calls.Single(c => c.CallID == CallID);
            ViewState.Add("Extension", call.Event.Client.Extension);
            if (call.Outbound)
            {
                lbCallerInfo.Text = call.Login;
                lbClientInfo.Text = String.Format("{0:(###)###-####}", call.Number);
            }
            else
            {
                //lbCallerInfo.Text = String.Format("{0:(###)###-####}", call.Number);
                lbCallerInfo.Text = call.Number.ToString();
                lbClientInfo.Text = call.Event.Client.Name + "(" + call.Event.Client.Number + ")";
            }

            int numMessages = (from m in db.Messages
                               where m.Call.Event.ClientID == call.Event.Client.ClientID && m.Active == true
                               select m).Count();
            if (numMessages > 0)
                lkClientMessages.Text = numMessages.ToString() + " messages";
            lkClientMessages.NavigateUrl = "client.aspx?ID=" + call.Event.Client.ClientID;
            lbGreeting.Text = call.Event.Client.Greeting;
            lbScratchpad.Text = call.Event.Client.Scratchpad;
            tbEditScratchpad.Text = call.Event.Client.Scratchpad;
            lbInstructions.Text = call.Event.Client.Instructions;
            tbCallerNumber.Text = call.Number;

            //Set page title
            this.Title = call.Event.Client.Name + "(" + call.Event.Client.Number.Trim() + ")";

            //Set Specific Instructions
            var specificInstructions = from specInst in db.SpecificInstructions
                                       where specInst.ClientID == call.Event.Client.ClientID
                                       select specInst;
            ddSpecificInstructions.Items.Clear();
            if (specificInstructions.Count() > 0)
            {
                ddSpecificInstructions.Visible = true;
                lbSpecificInstructions.Text = specificInstructions.First().Instructions;
            }
            foreach (var instruction in specificInstructions)
                ddSpecificInstructions.Items.Add(new ListItem(instruction.Description, instruction.SpecificInstructionID.ToString()));
            lkWebsite.Text = call.Event.Client.Website;
            lkWebsite.NavigateUrl = "http://" + call.Event.Client.Website;
            lkWebsite.Target = "_blank";

            //Set number links
            var phoneNumbers = from n in db.Numbers
                               where n.NumberType.Phone == true && n.ClientID == call.Event.ClientID
                               select n;

            lvNumbers.DataSource = phoneNumbers;
            lvNumbers.DataBind();

            //Populate Clients Emails
            var emails = from em in db.Emails
                         where em.ClientID == call.Event.ClientID
                         select em;

            foreach (var email in emails)
                cbEmail.Items.Add(new ListItem(email.Address));

            //Populate clients messaging numbers
            var numbers = from n in db.Numbers
                          where n.ClientID == call.Event.ClientID
                          select n;
            foreach (var number in numbers)
            {
                if (number.NumberType.FaxCapable == true)
                    cbFax.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                if (number.NumberType.SMSCapable == true)
                    cbSMS.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                if (number.NumberType.AlphaPageCapable == true)
                    cbAlpha.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
                if (number.NumberType.NumericPageCapable == true)
                    cbNumeric.Items.Add(new ListItem(number.Number1, number.NumberID.ToString()));
            }

            //Set up custom message fields
            var customFields = from fields in db.CustomFields
                               where fields.ClientID == call.Event.ClientID
                               select fields;
            foreach (var f in customFields)
            {
                Label customLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$" + f.FieldColumn.FieldName + "_Label");
                customLabel.Text = f.Name;
                customLabel.Visible = true;
                this.Master.FindControl("ctl00$ContentPlaceHolder1$" + f.FieldColumn.FieldName).Visible = true;
            }

        }
        GetToday();
    }

    protected void PhoneLink_Click(object sender, CommandEventArgs e)
    {
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call")+12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }
            
            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = myChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "*2" + e.CommandName;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }
    }

    protected void btCancelCall_Click(object sender, EventArgs e)
    {
        try
        {
            manager.Login();	// Login only (fast)
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call")+12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }

            string ext = db.Calls.Single(c => c.CallID == (int)ViewState["CallID"]).Event.Client.Extension;

            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = ext;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }

        CloseWindow();

    }

    protected void btUpdateScratchpad_Click(object sender, EventArgs e)
    {
        Client client = db.Calls.Single(c => c.CallID == (int)ViewState["CallID"]).Event.Client;
        client.Scratchpad = tbEditScratchpad.Text;
        db.SubmitChanges();
        lbScratchpad.Text = tbEditScratchpad.Text;
    }

    protected void ddSpecificInstructions_SelectedIndexChanged(object sender, EventArgs e)
    {
        lbSpecificInstructions.Text = (from si in db.SpecificInstructions where si.SpecificInstructionID == Convert.ToInt32(ddSpecificInstructions.SelectedValue) select si.Instructions).Single();
    }

    protected void btChooseAction_Command(object sender, CommandEventArgs e)
    {
        ActionTaken action = new ActionTaken();
        action.CallID = (int)ViewState["CallID"];
        action.ActionID = Convert.ToByte(e.CommandName);
        action.Timestamp = DateTime.Now;
        db.ActionTakens.InsertOnSubmit(action);
        db.SubmitChanges();
        lvActionsTaken.DataBind();
    }

    protected void btSendMessage_Click(object sender, EventArgs e)
    {
        //Send emails
        MailAddressCollection to = new MailAddressCollection();
        foreach (ListItem cb in cbEmail.Items)
        {
            if (cb.Selected)
                to.Add(new MailAddress(cb.Value));
        }
        if (to.Count > 0)
            SendEmail(to, tbMessage.Text, getCustomFields());

        foreach (ListItem cb in cbSMS.Items)
        {
            if (cb.Selected)
            {
                //Goes one by one through the optional fields and determines if they are to be sent
                Number number = db.Numbers.Single(n => n.NumberID.ToString() == cb.Value);
                string message = "";
                if (tbCallerName.Text != "" && number.IncludeCallerName == true)
                    message += "Caller:" + tbCallerName.Text + " ";
                if (tbCallerNumber.Text != "" && number.IncludeCallerNumber == true)
                    message += "Number:" + tbCallerNumber.Text + " ";
                if (tbCallerAddress.Text != "" && number.IncludeCallerAddress == true)
                    message += "Address:" + tbCallerAddress.Text + " ";
                if (CustomText1.Text != "" && number.IncludeCustomText1 == true)
                    message += CustomText1_Label.Text + ": " + CustomText1.Text + " ";
                if (CustomText2.Text != "" && number.IncludeCustomText2 == true)
                    message += CustomText2_Label.Text + ": " + CustomText2.Text + " ";
                if (CustomText3.Text != "" && number.IncludeCustomText3 == true)
                    message += CustomText3_Label.Text + ": " + CustomText3.Text + " ";

                if (CustomNumeric1.Text != "" && number.IncludeCustomNumeric1 == true)
                    message += CustomNumeric1_Label.Text + ": " + CustomNumeric1.Text + " ";
                if (CustomNumeric2.Text != "" && number.IncludeCustomNumeric2 == true)
                    message += CustomNumeric2_Label.Text + ": " + CustomNumeric2.Text + " ";
                if (CustomNumeric3.Text != "" && number.IncludeCustomNumeric3 == true)
                    message += CustomNumeric3_Label.Text + ": " + CustomNumeric3.Text + " ";

                if (CustomDateTime1.Text != "" && number.IncludeCustomDateTime1 == true)
                    message += CustomDateTime1_Label.Text + ": " + CustomDateTime1.Text + " ";
                if (CustomDateTime2.Text != "" && number.IncludeCustomDateTime2 == true)
                    message += CustomDateTime2_Label.Text + ": " + CustomDateTime2.Text + " ";
                if (CustomDateTime3.Text != "" && number.IncludeCustomDateTime3 == true)
                    message += CustomDateTime3_Label.Text + ": " + CustomDateTime3.Text + " ";

                if (CustomBit1.Text != "" && number.IncludeCustomBit1 == true)
                    message += CustomBit1_Label.Text + ": " + CustomText1.Text + " ";
                if (CustomBit2.Text != "" && number.IncludeCustomBit2 == true)
                    message += CustomBit2_Label.Text + ": " + CustomText2.Text + " ";
                if (CustomBit3.Text != "" && number.IncludeCustomBit3 == true)
                    message += CustomBit3_Label.Text + ": " + CustomText3.Text + " ";

                if (tbMessage.Text != "")
                    message += " " + tbMessage.Text;

                sendSMS(number.Number1, number.Provider.SMSEmailAddress, message);
            }
        }
        foreach (ListItem cb in cbFax.Items)
        {
            if (cb.Selected)
            {
                //Code to Fax
            }
        }

        foreach (ListItem cb in cbAlpha.Items)
        {
            if (cb.Selected)
            {
                //Code to alpha page
            }
        }
        foreach (ListItem cb in cbNumeric.Items)
        {
            if (cb.Selected)
            {
                //Code to numeric page
            }
        }
        InsertMessage(false);
    }

    protected void btQueueMessage_Click(object sender, EventArgs e)
    {
        InsertMessage(true);
    }

    NameValueCollection getCustomFields()
    {
        NameValueCollection customFields = new NameValueCollection();
        for (int i = 1; i <= 3; i++)
        {
            Label textLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomText" + i + "_Label");
            TextBox textField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomText" + i);
            if (textField.Text != "")
                customFields.Add(textLabel.Text, textField.Text);
            Label DateTimeLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomDateTime" + i + "_Label");
            TextBox DateTimeField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomDateTime" + i);
            if (DateTimeField.Text != "")
                customFields.Add(DateTimeLabel.Text, DateTimeField.Text);
            Label numericLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomNumeric" + i + "_Label");
            TextBox numericField = (TextBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomNumeric" + i);
            if (numericField.Text != "")
                customFields.Add(numericLabel.Text, numericField.Text);
            Label bitLabel = (Label)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomBit" + i + "_Label");
            CheckBox bitField = (CheckBox)this.Master.FindControl("ctl00$ContentPlaceHolder1$CustomBit" + i);
            if (bitField.Visible)
                customFields.Add(textLabel.Text, CheckedYesNo(bitField.Checked));
        }
        return customFields;
    }

    void InsertMessage(bool active)
    {
        Message message = new Message();
        message.CallID = (int)ViewState["CallID"];
        message.TimeStamp = DateTime.Now;
        message.Active = active;
        message.CallerName = tbCallerName.Text;
        message.CallerNumber = tbCallerNumber.Text;
        message.CallerAddress = tbCallerAddress.Text;
        message.Text = tbMessage.Text;
        if (CustomText1_Label.Text != "")
            message.CustomText1_Label = CustomText1_Label.Text;
        if (CustomText1.Text != "")
            message.CustomText1 = CustomText1.Text;
        if (CustomText2_Label.Text != "")
            message.CustomText1_Label = CustomText2_Label.Text;
        if (CustomText2.Text != "")
            message.CustomText2 = CustomText2.Text;
        if (CustomText3_Label.Text != "")
            message.CustomText3_Label = CustomText3_Label.Text;
        if (CustomText3.Text != "")
            message.CustomText3 = CustomText3.Text;

        if (CustomNumeric1_Label.Text != "")
            message.CustomNumeric1_Label = CustomNumeric1_Label.Text;
        if (CustomNumeric1.Text != "")
            message.CustomNumeric1 = Convert.ToDecimal(CustomNumeric1.Text);
        if (CustomNumeric2_Label.Text != "")
            message.CustomText1_Label = CustomNumeric2_Label.Text;
        if (CustomNumeric2.Text != "")
            message.CustomNumeric2 = Convert.ToDecimal(CustomNumeric2.Text);
        if (CustomNumeric3_Label.Text != "")
            message.CustomNumeric3_Label = CustomNumeric3_Label.Text;
        if (CustomNumeric3.Text != "")
            message.CustomNumeric3 = Convert.ToDecimal(CustomNumeric3.Text);

        if (CustomDateTime1_Label.Text != "")
            message.CustomDateTime1_Label = CustomDateTime1_Label.Text;
        if (CustomDateTime1.Text != "")
            message.CustomDateTime1 = Convert.ToDateTime(CustomDateTime1.Text);
        if (CustomDateTime2_Label.Text != "")
            message.CustomText1_Label = CustomDateTime2_Label.Text;
        if (CustomDateTime2.Text != "")
            message.CustomDateTime2 = Convert.ToDateTime(CustomDateTime2.Text);
        if (CustomDateTime3_Label.Text != "")
            message.CustomDateTime3_Label = CustomDateTime3_Label.Text;
        if (CustomDateTime3.Text != "")
            message.CustomDateTime3 = Convert.ToDateTime(CustomDateTime3.Text);

        if (CustomBit1_Label.Text != "")
            message.CustomBit1_Label = CustomBit1_Label.Text;
        if (CustomBit1.Text != "")
            message.CustomBit1 = CustomBit1.Checked;
        if (CustomBit2_Label.Text != "")
            message.CustomText1_Label = CustomBit2_Label.Text;
        if (CustomBit2.Text != "")
            message.CustomBit2 = CustomBit2.Checked;
        if (CustomBit3_Label.Text != "")
            message.CustomBit3_Label = CustomBit3_Label.Text;
        if (CustomBit3.Text != "")
            message.CustomBit3 = CustomBit3.Checked;
              
        db.Messages.InsertOnSubmit(message);
        db.SubmitChanges();
    }

    static string sendSMS(string number, string providerEmail, string message)
    {
        MailMessage objEmail = new MailMessage();
        objEmail.From = new MailAddress("messagecenter@bryan800.com");
        objEmail.Body = message;
        objEmail.To.Add(number + providerEmail);

        SmtpClient mailServer = new SmtpClient();
        try
        {
            mailServer.Send(objEmail);
            return ("Your Email has been sent sucessfully - Thank You");
        }
        catch (Exception exc)
        {
            return ("Send failure: " + exc.ToString());
        }
    }

    protected void btVoicemail_Click(object sender, EventArgs e)
    {
        //Send Command to place call to voicemail
        try
        {
            manager.Login();
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call") + 12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }
            string ext = db.Clients.Single(c => c.ClientID == (int)ViewState["ClientID"]).Extension;
            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "*86"+ ext;
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }
    }

    protected void btPark_Click(object sender, EventArgs e)
    {
        //Push existing text into Application State
        string key = (string)ViewState["CID"];
        Dictionary<string, OpenCall> openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];
        OpenCall openCall = openCalls[key];
        openCall.CallerName = tbCallerName.Text;
        openCall.CallerNumber = tbCallerNumber.Text;
        openCall.CallerAddress = tbCallerAddress.Text;
        openCall.Message = tbMessage.Text;

        openCalls[key] = openCall;
        Application["OpenCalls"] = openCalls;
        
        //Send Command to place call back in queue
        try
        {
            manager.Login();
        }
        catch (Exception ex)
        {
            manager.Logoff();
            return;
        }

        ExtensionStateAction stateAction = new ExtensionStateAction();
        stateAction.Exten = Request.QueryString["ext"];
        ExtensionStateResponse stateResponse = (ExtensionStateResponse)manager.SendAction(stateAction, TIMEOUT);
        if (stateResponse.IsSuccess())
        {
            string myChannel = "";
            string theirChannel = "";

            CommandAction showChannelsAction = new CommandAction();
            showChannelsAction.Command = "show channels";
            CommandResponse showChannelsResponse = (CommandResponse)manager.SendAction(showChannelsAction, TIMEOUT);
            foreach (string result in showChannelsResponse.Result)
            {
                if (stateResponse.Hint.Length <= result.Length)
                {
                    if (result.Substring(0, stateResponse.Hint.Length) == stateResponse.Hint)
                    {
                        myChannel = result.Substring(0, result.IndexOf(" "));
                        int bridgeIndex = result.IndexOf("Bridged Call") + 12;
                        theirChannel = result.Substring(bridgeIndex, result.Length - bridgeIndex).Trim();
                        break;
                    }
                }
            }

            RedirectAction redirectAction = new RedirectAction();
            redirectAction.Channel = theirChannel;
            redirectAction.Context = "internal";
            redirectAction.Exten = "9000";
            redirectAction.Priority = 1;

            try
            {
                ManagerResponse redirectResponse = manager.SendAction(redirectAction, 10000);
            }
            catch (Exception ex) { }

            manager.Logoff();
        }

        CloseWindow();
    }

    protected void lvActionsTaken_DataBinding(object sender, EventArgs e)
    {
        var actionsTaken = from at in db.ActionTakens
                           where at.CallID == (int)ViewState["CallID"]
                           select at;
        lvActionsTaken.DataSource = actionsTaken;
    }

    protected void btAddActionTaken_Click(object sender, EventArgs e)
    {
        ActionTaken actionTaken = new ActionTaken();

    }

    protected void lvFollowUps_DataBinding(object sender, EventArgs e)
    {
        var followUps = from f in db.FollowUps
                        where f.CallID == (int)ViewState["CallID"]
                        select f;
        lvFollowUps.DataSource = followUps;                        
    }

    protected void btAddFollowUp_Click(object sender, EventArgs e)
    {
        FollowUp followUp = new FollowUp();
        followUp.CallID = (int)ViewState["CallID"];
        followUp.Reminder = DateTime.Now.AddMinutes(15);
        followUp.Note = tbFollowUpNote.Text;
        db.FollowUps.InsertOnSubmit(followUp);
        db.SubmitChanges();
        lvFollowUps.DataBind();
    }

    protected void btCloseNoBill_Click(object sender, EventArgs e)
    {
        //Remove Application State Entry

        //string key = (string)ViewState["CID"];
        //Dictionary<string, OpenCall> openCalls = (Dictionary<string, OpenCall>)Application["OpenCalls"];
        //openCalls.Remove(key);
        //Application["OpenCalls"] = openCalls;

        CloseWindow();
    }

    #region On-Call Schedule

    #region Get/Set for Rows/Cols
    protected int Rows
    {
        get { return ViewState["Rows"] != null ? (int)ViewState["Rows"] : 0; }
        set { ViewState["Rows"] = value; }
    }

    // Columns property to hold the Columns in the ViewState
    protected int Columns
    {
        get { return ViewState["Columns"] != null ? (int)ViewState["Columns"] : 0; }
        set { ViewState["Columns"] = value; }
    }
    #endregion

    #region Get Events

    public List<OnCallEntry> GetOCEntries(SqlCommand command)
    {
        List<OnCallEntry> newList = new List<OnCallEntry>();
        SqlConnection conn = new SqlConnection(OnCallConnection);
        try
        {
            conn.Open();
        }
        catch (Exception ex) { System.Console.WriteLine("Error connecting to SQL Database: " + ex.ToString()); }
        command.Connection = conn;
        SqlDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            newList.Add(new OnCallEntry(reader));
        }
        return newList;
    }

    protected void GetOCToday(object sender, EventArgs e)
    {
        ENTRIES = GetOCEntries(getSelectDateCommand((int)ViewState["ClientID"], new SqlDateTime(DateTime.Today)));
        Rows = ENTRIES.Count;
        Columns = 2;
        CreateDynamicTable();
    }

    protected void GetOCNext12Hours(object sender, EventArgs e)
    {
        //If current time is PM, get tomorrow's events and todays and combine them
        //to get the events for the next 12 hours
        if (DateTime.Now.TimeOfDay > new TimeSpan(12, 0, 0))
        {
            List<OnCallEntry> tomorrowEntries = new List<OnCallEntry>();
            DateTime tomorrow = DateTime.Today.AddDays(1);
            //Get tomorrow's entries
            tomorrowEntries = GetOCEntries(getSelectDateCommand((int)ViewState["ClientID"], new SqlDateTime(tomorrow)));
            ENTRIES = GetOCEntries(getSelectDateCommand((int)ViewState["ClientID"], new SqlDateTime(DateTime.Today)));

            for (int i = 0; i < ENTRIES.Count; i++)
            {
                if (ENTRIES[i].EndTime < DateTime.Now)
                    ENTRIES.RemoveAt(i);
            }
            DateTime twelveHoursFromNow = DateTime.Now.AddHours(12);
            for (int i = 0; i < tomorrowEntries.Count; i++)
            {
                if (tomorrowEntries[i].StartTime < twelveHoursFromNow)
                    ENTRIES.Add(tomorrowEntries[i]);
            }
        }
        // If current time is AM, just get the events for today and remove the ones that are
        // starting after 12 hours from right now.
        else
        {
            ENTRIES = GetOCEntries(getSelectDateCommand((int)ViewState["ClientID"], new SqlDateTime(DateTime.Today)));
            DateTime twelveHoursFromNow = DateTime.Now.AddHours(12);
            for (int i = 0; i < ENTRIES.Count; i++)
            {
                if (ENTRIES[i].StartTime < twelveHoursFromNow)
                    ENTRIES.RemoveAt(i);
            }
        }
        Rows = ENTRIES.Count;
        Columns = 2;
        CreateDynamicTable();
    }

    #endregion

    #region SQL Command

    public SqlCommand getSelectDateCommand(int client, SqlDateTime today)
    {
        string query = "SELECT * FROM data" + " WHERE (ClientID = @cID AND ((StartDate = @today) OR (StartDate < @today AND EndDate > @today  AND (Daily = 1 OR (Weekly = 1 AND ";
        DateTime dt = (DateTime)today;
        switch (dt.DayOfWeek)
        {
            case DayOfWeek.Monday:
                query += "Mon = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Tuesday:
                query += "Tue = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Wednesday:
                query += "Wed = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Thursday:
                query += "Thu = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Friday:
                query += "Fri = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Saturday:
                query += "Sat = 1))))) ORDER BY StartTime";
                break;
            case DayOfWeek.Sunday:
                query += "Sun = 1))))) ORDER BY StartTime";
                break;
        };
        SqlCommand comm = new SqlCommand(query);
        comm.Parameters.Add(new SqlParameter("@cID", client));
        comm.Parameters.Add(new SqlParameter("@today", today));
        return comm;
    }

    #endregion

    #region Dynamic Table Creation

    private void CreateDynamicTable()
    {
        OnCallPlaceHolder.Controls.Clear();

        int tblRows = Rows;
        int tblCols = Columns;
        Table tbl = new Table();
        OnCallPlaceHolder.Controls.Add(tbl);

        for (int i = 0; i < ENTRIES.Count; i++)
        {
            TableRow tr = new TableRow();

            TableCell tc1 = new TableCell();
            Label label1 = new Label();

            TableCell tc2 = new TableCell();
            Label label2 = new Label();

            bool current = false;

            if (!ENTRIES[i].StartTime.IsNull && !ENTRIES[i].EndTime.IsNull)
            {
                DateTime d1 = (DateTime)ENTRIES[i].StartTime;
                DateTime d2 = (DateTime)ENTRIES[i].EndTime;
                if (d1.TimeOfDay.TotalMinutes < DateTime.Now.TimeOfDay.TotalMinutes &&
                    d2.TimeOfDay.TotalMinutes > DateTime.Now.TimeOfDay.TotalMinutes)
                    current = true;
                label1.Text = String.Format("{0:t}", d1) + "\t\t-\t\t" + String.Format("{0:t}", d2);
            }
            else
                label1.Text = "NULL";

            if (current)
            {
                currentLabelStyle.Width = 150;
                label1.ApplyStyle(currentLabelStyle);
                currentLabelStyle.Width = 300;
                label2.ApplyStyle(currentLabelStyle);
            }
            else
            {
                labelStyle.Width = 150;
                label1.ApplyStyle(labelStyle);
                labelStyle.Width = 300;
                label2.ApplyStyle(labelStyle);
            }

            label2.Text = ENTRIES[i].Note;

            tc1.Controls.Add(label1);
            tr.Cells.Add(tc1);
            tc2.Controls.Add(label2);
            tr.Cells.Add(tc2);

            // Add the TableRow to the Table
            tbl.Rows.Add(tr);
        }
        // This parameter helps determine in the LoadViewState event,
        // whether to recreate the dynamic controls or not
        ViewState["dynamictable"] = true;
    }

    #endregion

    protected override void LoadViewState(object earlierState)
    {
        base.LoadViewState(earlierState);
        if (ViewState["dynamictable"] == null)
            CreateDynamicTable();
    }

    #endregion

    string CheckedYesNo(bool isChecked)
    {
        if (isChecked)
            return "Yes";
        else
            return "No";
    }

    static void SendEmail(MailAddressCollection to, string message, NameValueCollection customfields)
    {
        MailMessage mail = new MailMessage();

        mail.From = new MailAddress("messagecenter@bryan800.com");
        mail.Subject = "A message just arrived for you";
        mail.IsBodyHtml = true;
        string body = "<html><body>";
        body += (message + "<br /><br />");
        foreach (string key in customfields.AllKeys)
            body += (key + ": " + customfields[key] + "<br /><br />");
        body += "</body></html>";
        mail.Body = body;
        foreach (MailAddress adr in to)
            mail.To.Add(adr);

        SmtpClient mailServer = new SmtpClient();
        mailServer.Send(mail);
        /*
        object userState = mail;
        //wire up the event for when the Async send is completed
        mailServer.SendCompleted += new SendCompletedEventHandler(SmtpClient_OnCompleted);
        mailServer.SendAsync(mail, userState);*/
    }

    public static void SmtpClient_OnCompleted(object sender, AsyncCompletedEventArgs e)
    {
        //Get the Original MailMessage object
        MailMessage mail = (MailMessage)e.UserState;

        //write out the subject
        string subject = mail.Subject;

        if (e.Cancelled)
            Console.WriteLine("Send canceled for mail with subject [{0}].", subject);
        if (e.Error != null)
            Console.WriteLine("Error {1} occurred when sending mail [{0}] ", subject, e.Error.ToString());
        else
            Console.WriteLine("Message [{0}] sent.", subject);
    }

    protected void lvOnCall_DataBinding(object sender, EventArgs e)
    {
        var onCallEvents = from oc in db.OnCallSchedules
                           where oc.StartDate.Value.Date <= DateTime.Now.Date && oc.EndDate.Value.Date >= DateTime.Now.Date
                           select oc;
        lvOnCall.DataSource = onCallEvents;
    }

    protected void LinqDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {
        foreach (KeyValuePair<string, object> kvp in e.WhereParameters)
        {
            if (kvp.Value == null)
            {
                e.Cancel = true;
                return;
            }
        }
    }

    protected void CloseWindow()
    {
        string closeScript = "<script language=javascript>window.open('','_self','');window.close();</script>";
        if (!Page.ClientScript.IsStartupScriptRegistered("clientScript"))
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "clientScript", closeScript);
    }
}
